/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.generator;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.AST;

/**
 * @author liu_wei
 */
public abstract class BaseGenerator {
    protected AST ast;
    protected List<BaseGenerator> childGenerators;
    protected BaseGenerator parentGenerator;

    public void setAst(AST value) {
        ast = value;
    }

    private BaseGeneratorContext context;

    protected BaseGenerator() {
        try {
            ast = AST.newAST(AST.JLS3);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new RuntimeException(e);
        }

    }

    protected BaseGeneratorContext getContext() {
        return context;
    }

    public void initialize() {
        context = createContext();
        context.setAst(ast);
        beforeInitialize();
        doInitialize();
        afterInitialize();
        childGenerators = createChildGenerators();
        initChildContext();
    }

    public void generate() {
        beforeGenerate();
        generateChildren();
        doGenerate();
        afterGenerate();
    }

    // region Context
    protected abstract BaseGeneratorContext createContext();

    private void initChildContext() {
        if (childGenerators == null || childGenerators.size() < 1)
            return;
        for (BaseGenerator childGenerator : childGenerators) {
            childGenerator.parentGenerator = this;
            childGenerator.setAst(ast);
            childGenerator.initialize();
        }
    }

    // endregion

    // region ���ӹ�ϵ
    /// <summary>
    /// ������������
    /// </summary>
    protected void addChildGenerators(BaseGenerator childGenerator) {
        if (childGenerators == null) {
            childGenerators = new ArrayList<BaseGenerator>();
        }
        childGenerators.add(childGenerator);
    }

    /// <summary>
    /// ������������
    /// </summary>
    // protected abstract void CreateChildGenerators();
    protected ArrayList<BaseGenerator> createChildGenerators() {
        return (ArrayList<BaseGenerator>) childGenerators;
    }

    /// <summary>
    /// ��ȡ��������
    /// </summary>
    /// <returns></returns>
    public BaseGenerator getParentGenerator() {
        return parentGenerator;
    }
    // endregion

    // region Generate
    protected void doGenerate() {
    }

    protected void beforeGenerate() {

    }

    protected void afterGenerate() {

    }

    private void generateChildren() {
        if (childGenerators == null || childGenerators.size() < 1)
            return;
        for (BaseGenerator childGenerator : childGenerators) {
            childGenerator.generate();
        }
    }

    // endregion

    // region Initialize

    protected void doInitialize() {
    }

    protected void beforeInitialize() {

    }

    protected void afterInitialize() {

    }

    // endregion

    protected void addImport(String importName) {
        if (parentGenerator != null) {
            parentGenerator.addImport(importName);
        }
    }

}
